package org.thanos.iot.service.file;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.thanos.iot.entity.file.SysFile;
import org.thanos.iot.enums.FileType;
import org.thanos.iot.enums.ImageType;
import org.thanos.iot.dao.file.SysFileMapper;
import org.thanos.iot.util.file.FilePathUtil;
import org.thanos.iot.util.string.StrUtil;

import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@Service("sysFileService")
public class SysFileServiceImpl implements SysFileService {

    @Value("${file.imagePath}")
    private String imagePath;

    @Value("${file.defaultPath}")
    private String defaultPath;

    @Autowired
    private SysFileMapper sysFileMapper;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public SysFile saveFile(MultipartFile multipartFile) throws IOException {
        // file origin name
        String filename = multipartFile.getOriginalFilename();
        int fileType;
        // file dest name
        String prefix = filename.substring(filename.lastIndexOf(StrUtil.DOT) + 1);
        String destFilename = UUID.randomUUID().toString().replace(StrUtil.DASHED, StrUtil.EMPTY) + StrUtil.DOT + prefix;
        //file directory
        String date = LocalDateTime.now().format(DateTimeFormatter.ISO_DATE);
        String pathUrl = StrUtil.EMPTY;
        if (Stream.of(ImageType.values()).map(ImageType::getCode).anyMatch(filename::contains)) {
            fileType = FileType.IMAGE.getId();
            pathUrl += imagePath + date;
        } else {
            fileType = FileType.OTHER.getId();
            pathUrl += defaultPath + date;
        }
        File fileUrl = new File(FilePathUtil.getBaseJarPath() + pathUrl);
        //save image
        if (!fileUrl.exists()) {
            fileUrl.mkdirs();
        }
        File destImage = new File(fileUrl, destFilename);
        multipartFile.transferTo(destImage);
        //save to db
        SysFile sysFile = new SysFile();
        sysFile.setType(fileType);
        sysFile.setPath(pathUrl + StrUtil.SLASH + destFilename);
        sysFile.setName(filename);
        sysFileMapper.insertFile(sysFile);
        return sysFile;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteObsoleteFiles(List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        // 替换为缓存插入
        List<SysFile> deleteFiles = sysFileMapper.selectFilesByIds(ids);
        log.error("deleteObsoleteFiles time: {}, delete file: {}", System.currentTimeMillis(), deleteFiles);
        //delete file in system
        if (CollectionUtils.isEmpty(deleteFiles)) {
            return;
        }
        for (SysFile sysFile : deleteFiles) {
            File file = new File(FilePathUtil.getBaseJarPath() + sysFile.getPath());
            if (file.isFile() && file.exists()) {
                file.delete();
            }
        }
        sysFileMapper.deleteFilesByIds(deleteFiles.stream().map(SysFile::getId).collect(Collectors.toList()));
    }
}


